package jpack.sz;

import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Denis Migol
 * 
 */
public class SzCommandBuilder {

	// TODO

	private String app;

	private String command;

	private final Set<String> switches = new HashSet<String>();

	private File archive;

	private final List<String> wildcards = new ArrayList<String>();

	private final List<File> files = new ArrayList<File>();

	private final List<File> listFiles = new ArrayList<File>();

	/**
	 * 
	 * @param app
	 * @return
	 */
	private String correctApp(final String app) {
		return app == null ? Sz._7Z : app;
	}

	/**
	 * rar or winrar
	 * 
	 * @param app
	 * @return
	 */
	public SzCommandBuilder setApp(final String app) {
		this.app = correctApp(app);
		return this;
	}

	/**
	 * 
	 * @param command
	 * @return
	 */
	public SzCommandBuilder setCommand(final String command) {
		this.command = command;
		return this;
	}

	/**
	 * 
	 * @param swtch
	 * @return
	 */
	private String correctSwitch(final String swtch) {
		String s = swtch;
		if (s != null && (s.startsWith("-") || s.startsWith("/")) && !"-".equals(s)) {
			s = s.substring(1, s.length());
		}
		return s;
	}

	/**
	 * 
	 * @param swtch
	 * @return
	 */
	public SzCommandBuilder addSwitch(final String swtch) {
		switches.add(correctSwitch(swtch));
		return this;
	}

	/**
	 * 
	 * @param archive
	 * @return
	 */
	public SzCommandBuilder setArchive(final File archive) {
		this.archive = archive;
		return this;
	}

	/**
	 * 
	 * @param wildcard
	 * @return
	 */
	public SzCommandBuilder addWildcard(final String wildcard) {
		wildcards.add(wildcard);
		return this;
	}

	/**
	 * 
	 * @param file
	 * @return
	 */
	public SzCommandBuilder addFile(final File file) {
		files.add(file);
		return this;
	}

	/**
	 * 
	 * @param listFile
	 * @return
	 */
	public SzCommandBuilder addListFile(final File listFile) {
		listFiles.add(listFile);
		return this;
	}

	// build methods

	/**
	 * 
	 * @return
	 */
	private String buildApp() {
		return correctApp(app);
	}

	/**
	 * 
	 * @return
	 */
	private String buildCommand() {
		return command;
	}

	/**
	 * 
	 * @param sb
	 * @return
	 */
	private String deleteLastChar(final StringBuilder sb) {
		final int length = sb.length();
		if (length > 0) {
			sb.deleteCharAt(length - 1);
		}
		return sb.toString();
	}

	/**
	 * 
	 * @return
	 */
	private String buildSwitches() {
		final StringBuilder ret = new StringBuilder();
		for (final String swtch : switches) {
			if (swtch != null && !"".equals(swtch)) {
				ret.append('-' + swtch + ' ');
			}
		}
		return deleteLastChar(ret);
	}

	/**
	 * 
	 * @param file
	 * @return
	 */
	private String getFilePath(final File file) {
		return "\"" + file.getAbsolutePath() + "\"";
	}

	/**
	 * 
	 * @return
	 */
	private String buildArchive() {
		return getFilePath(archive);
	}

	/**
	 * 
	 * @return
	 */
	private String buildFiles() {
		final StringBuilder ret = new StringBuilder();
		for (final File file : files) {
			ret.append(getFilePath(file) + ' ');
		}
		return deleteLastChar(ret);
	}

	/**
	 * 
	 * @return
	 */
	private String buildListFiles() {
		final StringBuilder ret = new StringBuilder();
		for (final File listFile : listFiles) {
			ret.append("\"" + '@' + listFile.getAbsolutePath() + "\"" + ' ');
		}
		return deleteLastChar(ret);
	}

	/**
	 * 
	 * @param sb
	 * @param string
	 */
	private void appendIfNotEmpty(final StringBuilder sb, final String string, final boolean space) {
		if (!"".equals(string)) {
			sb.append(space ? string + ' ' : string);
		}
	}

	/**
	 * 
	 * @return
	 */
	public String build() {
		final StringBuilder ret = new StringBuilder(buildApp() + ' ');
		ret.append(buildCommand() + ' ');
		appendIfNotEmpty(ret, buildSwitches(), true);
		appendIfNotEmpty(ret, buildArchive(), true);
		appendIfNotEmpty(ret, buildFiles(), true);
		appendIfNotEmpty(ret, buildListFiles(), false);
		return ret.toString().trim();
	}

	public static void main(final String[] args) {
		System.out.println(new SzCommandBuilder().setCommand("x").setArchive(new File("1.rar")).addSwitch("r").build());
	}
}
